package com.autumn.evaluator;

import java.io.Serializable;

//
// * 表示一个函数,区分类别和说明以及调用格式，对于友好交互提供使用帮助
// * call 表示该函数的回调委托
// 

import com.autumn.evaluator.annotation.FunctionRegister;
import com.autumn.util.ArgumentNullException;

/**
 * 函数
 */
public class Function implements Serializable {

	/**
	 * 序列号
	 */
	private static final long serialVersionUID = 5588703960148212135L;
	/**
	 * 获取函数名称
	 */
	private String name;

	public final String getName() {
		return name;
	}

	private void setName(String value) {
		name = value;
	}

	private String category;

	/**
	 * 获取函数类别
	 */
	public final String getCategory() {
		if (this.getAttribute() != null) {
			return this.getAttribute().category();
		}
		return category;
	}

	private String caption;

	/**
	 * 获取函数说明
	 */
	public final String getCaption() {
		if (this.getAttribute() != null) {
			// this.getAttribute().language = this.getLanguage();
			// this.getAttribute().configPath = this.getConfigPath();
			return this.getAttribute().caption();
		}
		return this.caption;
	}

	private FunctionRegister attribute = null;
	private boolean isLoadAttribute = false;

	private FunctionRegister getAttribute() {
		if (!this.isLoadAttribute) {
			isLoadAttribute = true;
			if (this.getCall() != null) {
				// Object[] Funs =
				// this.getCall().Method.GetCustomAttributes(FunctionRegister.class, false);

				// Set<Class<?>> types;
				// List<FunctionRegister> Funs = new ArrayList();
				// try {
				// types =
				// PackageUtils.getPackageAnnotationClass("com.autumn.evaluator.functions",
				// FunctionRegister.class);
				// for(Class<?> clazz : types) {
				// FunctionRegister[] annoArray =
				// clazz.getAnnotationsByType(FunctionRegister.class);
				// Funs.addAll(Arrays.asList(annoArray));
				// }
				// } catch (IOException e) {
				// e.printStackTrace();
				// }

				FunctionRegister[] funs = getFunClass().getAnnotationsByType(FunctionRegister.class);

				if (funs != null && funs.length > 0) {
					for (FunctionRegister fun : funs) {
						if (fun.name() != null) {
							if (fun.name().toLowerCase().equals(this.getName().toLowerCase())) {
								this.attribute = ((fun instanceof FunctionRegister) ? fun : null);
								break;
							}
						}
					}
				}
			}
		}
		return this.attribute;
	}

	public String format = "";

	/**
	 * 获取格式
	 */
	public final String getFormat() {
		return format;
	}

	/**
	 * 获取回调函数
	 */
	private Call call;

	public final Call getCall() {
		return call;
	}

	private void setCall(Call value) {
		call = value;
	}

	/**
	 * 获取函数参数集合
	 */
	private FunctionParams getFunParams;

	public final FunctionParams getGetFunParams() {
		return getFunParams;
	}

	private void setGetFunParams(FunctionParams value) {
		getFunParams = value;
	}

	/**
	 * 获取是否是动态参数集合(即参数数量不限制，如SUM)
	 */
	private boolean isDynamicParam;

	public final boolean getIsDynamicParam() {
		return isDynamicParam;
	}

	private void setIsDynamicParam(boolean value) {
		isDynamicParam = value;
	}

	private int dynamicParamType = VariantType.NULL;

	/**
	 * 获取动态参数类型
	 */
	public final int getDynamicParamType() {
		return this.dynamicParamType;
	}

	private int minParamCount = 0;

	/**
	 * 获取参数数量或最小参数数量
	 */
	public final int getMinParamCount() {
		return minParamCount;
	}

	/**
	 * 用来表示函数静态类的类类型
	 */
	private Class<?> funClass;

	public Class<?> getFunClass() {
		return funClass;
	}

	public void setFunClass(Class<?> funClass) {
		this.funClass = funClass;
	}

	/**
	 * 实例化 FUNCTION 类新实例
	 *
	 * @param name
	 *            函数名称
	 * @param category
	 *            函数类别
	 * @param caption
	 *            函数说明
	 * @throws ArgumentNullException/
	 */
	private Function(String name, String category, String caption) {
		if (name == null) {
			throw new ArgumentNullException("name");
		}
		this.setName(name);
		this.category = category;
		this.caption = caption;
		this.setGetFunParams(new FunctionParams(this));
	}

	/**
	 * 实例化 FUNCTION 类新实例
	 *
	 * @param name
	 *            函数名称
	 * @param category
	 *            函数类别
	 * @param caption
	 *            函数说明
	 * @param call
	 *            接口
	 * @param minParamCount
	 *            最小参数数量
	 * @throws ArgumentNullException/
	 */
	public Function(String name, String category, String caption, Call call, int minParamCount) {
		this(name, category, caption);
		if (call == null) {
			throw new ArgumentNullException("call");
		}
		this.setCall(call);
		this.setIsDynamicParam(false);
		this.dynamicParamType = VariantType.NULL;
		this.minParamCount = minParamCount;
	}

	/**
	 * 实例化 FUNCTION 类新实例
	 *
	 * @param name
	 *            函数名称
	 * @param category
	 *            函数类别
	 * @param caption
	 *            函数说明
	 * @param call
	 *            接口
	 * @param isDynamicParam
	 *            是否是动态参数
	 * @param dynamicParamType
	 *            动态参数类型
	 * @param minParamCount
	 *            最小参数数量
	 * @throws ArgumentNullException/
	 */
	public Function(String name, String category, String caption, Call call, boolean isDynamicParam,
			int dynamicParamType, int minParamCount) {
		this(name, category, caption);
		if (call == null) {
			throw new ArgumentNullException("call");
		}
		this.setCall(call);
		this.setIsDynamicParam(isDynamicParam);
		this.dynamicParamType = dynamicParamType;
		this.minParamCount = minParamCount;
	}

	public Function(String name, String category, String caption, Call call, boolean isDynamicParam,
			int dynamicParamType, int minParamCount, Class<?> funClass) {
		this(name, category, caption);
		if (call == null) {
			throw new ArgumentNullException("call");
		}
		this.setCall(call);
		this.setIsDynamicParam(isDynamicParam);
		this.dynamicParamType = dynamicParamType;
		this.minParamCount = minParamCount;
		this.funClass = funClass;
	}

	/**
	 * 实例化 FUNCTION 类新实例
	 *
	 * @param name
	 *            函数名称
	 * @param category
	 *            函数类别
	 * @param caption
	 *            函数说明
	 * @param call
	 *            接口
	 */
	public Function(String name, String category, String caption, Call call) {
		this(name, category, caption, call, 0);

	}

	/**
	 * 返回函数名称和说明
	 *
	 * @return
	 */
	@Override
	public String toString() {
		return this.getName();
	}

}